﻿namespace X2OPC.Core.DA
{
    using System;
    using System.Runtime.InteropServices;

    [ComVisible(true), Guid("CC0EEEE8-1D5D-4957-85A3-903E7CE78B89"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IOPCServer
    {
        /// <summary>
        /// 新增一个 OPCGroup 
        /// </summary>
        /// <param name="szName">组名。组名必须为UNICODE 码，不能是ASC码，而且不能和同一个客户程序创建的其它组的名字相同。如果没有定义组名，服务器会给它定义一个独有的名字。</param>
        /// <param name="bActive">如果值为FALSE，那么组被定义为不活动的。如果为TRUE，组被定义为活动的。</param>
        /// <param name="dwRequestedUpdateRate">客户程序定义的组最快的刷新速率，单位为毫秒，主要在OnDataChage 中使用。同样说明了要求CACHED DATA 的期望速率。如果此值为0，那么服务器必须以最快的实际速率刷新。</param>
        /// <param name="hClientGroup">客户程序提供的组句柄。</param>
        /// <param name="pTimeBias">时间戳指针。如果指针为空表示你希望使用系统默认时间戳。</param>
        /// <param name="pPercentDeadband">定义了死区参数。这个参数仅仅对本组内的模拟量有效。当模拟量的值变化超出死区，必须产生一个回调给客户程序。NULL 值代表0.0，即没有死区。</param>
        /// <param name="dwLCID">本组字符串操作时，服务器使用的语言。</param>
        /// <param name="phServerGroup">服务器为新的组产生的句柄。客户程序将采用服务器提供的句柄来要求服务器对组进行其它的操作。</param>
        /// <param name="pRevisedUpdateRate">服务器返回的实际刷新速率，这个值可能与客户程序要求的刷新速率不一样。注意：这个值可能也比服务器实际从设备获取数据和刷新CACHE 的速率要慢。</param>
        /// <param name="riid">期望接口类型 (如 IID_IOPCItemMgt)</param>
        /// <param name="ppUnk">返回接口指针，如果操作失败，返回NULL。</param>
        /// <returns>
        /// 返回码描述
        /// S_OK 操作成功。
        /// E_FAIL 操作失败。
        /// E_OUTOFMEMORY 没有足够的内存空间。
        /// E_INVALIDARG 功能非法。
        /// OPC_E_DUPLICATENAME Duplicate name not allowed.
        /// OPC_S_UNSUPPORTEDRAT
        /// E
        /// 服务器不支持指定的刷新速率，服务器
        /// 返回实际支持的刷新速率
        /// (pRevisedUpdateRate)。
        /// E_NOINTERFACE 服务器不支持请求的接口。
        /// </returns>

        [PreserveSig]
        int AddGroup([MarshalAs(UnmanagedType.LPWStr)] string szName, [MarshalAs(UnmanagedType.Bool)] bool bActive, int dwRequestedUpdateRate, int hClientGroup, IntPtr pTimeBias, IntPtr pPercentDeadband, int dwLCID, out int phServerGroup, out int pRevisedUpdateRate, ref Guid riid, [MarshalAs(UnmanagedType.IUnknown), Out] out object ppUnk);

        /// <summary>
        /// 取得错误信息字符串 
        /// </summary>
        /// <param name="dwError"></param>
        /// <param name="dwLocale"></param>
        /// <param name="ppString"></param>
        /// <returns></returns>
        [PreserveSig]
        int GetErrorString([In] int dwError, [In] int dwLocale, [MarshalAs(UnmanagedType.LPWStr)] out string ppString);

        /// <summary>
        ///  依据名称取得OPCGroup 的介面
        /// </summary>
        /// <param name="szName"></param>
        /// <param name="riid"></param>
        /// <param name="ppUnk"></param>
        [PreserveSig]
        int GetGroupByName([In, MarshalAs(UnmanagedType.LPWStr)] string szName, [In] ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppUnk);


        /// <summary>
        /// 取得 OPCServer的状态信息 
        /// </summary>
        /// <param name="ppServerStatus"></param>
        /// <returns></returns>
        [PreserveSig]
        int GetStatus(out ServerStatus ppServerStatus);

        /// <summary>
        /// 设定Clinet的名称RemoveGroup(hServerGroup, bForce)移除一个OPCGroup 
        /// </summary>
        /// <param name="hServerGroup">被删除组的句柄。</param>
        /// <param name="bForce">强制删除标志，即使组对象仍然在引用中。</param>
        /// <returns>
        /// E_FAIL 操作失败。
        /// E_OUTOFMEMO
        /// RY
        /// 没有足够的内存。
        /// E_INVALIDARG 功能非法。
        /// S_OK 操作成功。
        /// OPC_S_INUSE 组没有被删除，因为引用存在。组将被标记为删
        /// 除，当组的所有引用释放后，服务器会自动删除组。
        /// </returns>
        [PreserveSig]
        int RemoveGroup([In] int hServerGroup, [In, MarshalAs(UnmanagedType.Bool)] bool bForce);

        /// <summary>
        ///  产生一个OPCGroup 列举器
        /// </summary>
        /// <param name="dwScope"></param>
        /// <param name="riid"></param>
        /// <param name="ppUnk"></param>
        /// <returns></returns>
        [PreserveSig]
        int CreateGroupEnumerator([In] int dwScope, [In] ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppUnk);
    }
}
